package com.neusoft.po;

import java.util.List;

import com.neusoft.util.CommonUtil;

public class Credit {

	private Integer creditId;
	private String userId;
	private Integer channelType;// 来源
	private Integer num;
	private Long createTime = System.currentTimeMillis();// 创立时间
	private Long expiredTime;// 过期时间
	private Integer expired = 0;// 0:有效 1:无效
	private Integer used = 0;// 0:没使用 1:使用
	// 预留的企业进行更新积分过期时间的接口

	public void setExpiredTime(Long expiredTime) {
		this.expiredTime = expiredTime;
	}

	public void setNum(Integer num) {
		this.num = num;
	}

	public void setUsed(Integer used) {
		this.used = used;
	}

	// 充血功能模式和单一职责原则
	// 积分过期或者用完就会失效，deleted=1
	public boolean isAvailable() {// 对外接口

		if (!this.isExpired() && !this.isUsed()) {
			return true;
		}
		return false;
	}

	public boolean isExpired() {
		Long currentTime = System.currentTimeMillis();
		if (currentTime > this.expiredTime) {
			this.expired = 1;
			return true;
		}
		return false;
	}

	public boolean isUsed() {
		if (this.num <= 0) {
			this.used = 1;
			return true;
		}
		return false;
	}

	// 构造函数进行初始化数据不进行set暴露这些属性的修改权。
	public Credit(String userId, Integer channelType, Integer num, Long expiredTime) {
		super();
		this.userId = userId;
		this.channelType = channelType;
		this.num = num;
		this.expiredTime = expiredTime;
	}

	public Credit() {
		// TODO Auto-generated constructor stub
	}

	// 充血模型
	public int getTotalNum(List<Credit> list) {
		Integer totalCredit = 0;
		// 将list中所有expierdTime小于当前时间的积分删除,剩余积分求和
		for (Credit credit : list) {
			if (credit.isAvailable()) {
				totalCredit += credit.getNum();
			}
		}
		return totalCredit;
	}

	public void useOut(List<Credit> list) {
		for (Credit credit : list) {
			credit.setUsed(1);
		}
	}

	public Credit useCredit(List<Credit> list, Integer left) {
		// 将list中所有credit按expiredTime升序排序
		list.sort((o1, o2) -> o1.getExpiredTime().compareTo(o2.getExpiredTime()));

		// 遍历list,将积分从最早过期的开始扣除,直到left<=0
		for (Credit credit : list) {
			if (credit.isAvailable()) {
				if (credit.getNum() >= left) {
					Credit nw = new Credit(credit.userId, credit.channelType, credit.num - left, credit.expiredTime);
					left = 0;
					credit.setUsed(1);
					return nw;
				} else {
					left -= credit.getNum();
					credit.setUsed(1);
				}
			}
		}
		return null;
	}

	// some getter()

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public Integer getChannelType() {
		return channelType;
	}

	public void setChannelType(Integer channelType) {
		this.channelType = channelType;
	}

	public Integer getCreditId() {
		return creditId;
	}

	public Integer getNum() {
		return num;
	}

	public Long getCreateTime() {
		return createTime;
	}

	public Long getExpiredTime() {
		return expiredTime;
	}

}
